﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine;

namespace Miao.ML
{
    public class Deserializer
    {
        private static readonly List<Deserializer> deserializerList = new List<Deserializer>();

        private bool deserializing => winMLDeserializer.deserializing;

        private readonly WinMLDeserializer winMLDeserializer = new WinMLDeserializer();

        public static T FastDeserialize<T>(string text)
        {
            return FindDeserializer().Deserialize<T>(text);
        }
        public static T FastDeserializeFromFile<T>(string filePath)
        {
            return FindDeserializer().DeserializeFromFile<T>(filePath);
        }
        public static T FastDeserializeFromTextAsset<T>(TextAsset textAsset)
        {
            return FindDeserializer().DeserializeFromTextAsset<T>(textAsset);
        }

        public static Task<T> FastDeserializeAsync<T>(string text)
        {
            return FindDeserializer().DeserializeAsync<T>(text);
        }
        public static Task<T> FastDeserializeFromFileAsync<T>(string filePath)
        {
            return FindDeserializer().DeserializeFromFileAsync<T>(filePath);
        }
        public static Task<T> FastDeserializeFromTextAssetAsync<T>(TextAsset textAsset)
        {
            return FindDeserializer().DeserializeFromTextAssetAsync<T>(textAsset);
        }

        private static Deserializer FindDeserializer()
        {
            foreach (var deserializer in deserializerList)
            {
                if (deserializer.deserializing) continue;
                return deserializer;
            }
            Deserializer newDeserializer = new Deserializer();
            deserializerList.Add(newDeserializer);
            return newDeserializer;
        }

        public Deserializer()
        {
            WinMLForUnity.AddToDeserializer(winMLDeserializer);
        }

        public T Deserialize<T>(string text)
        {
            return winMLDeserializer.Deserialize<T>(text);
        }
        public T DeserializeFromFile<T>(string filePath)
        {
            return winMLDeserializer.DeserializeFromFile<T>(filePath);
        }
        public T DeserializeFromTextAsset<T>(TextAsset textAsset)
        {
            return Deserialize<T>(textAsset.text);
        }

        public async Task<T> DeserializeAsync<T>(string text)
        {
            return  await winMLDeserializer.DeserializeAsync<T>(text);
        }
        public async Task<T> DeserializeFromFileAsync<T>(string filePath)
        {
            return await winMLDeserializer.DeserializeFromFileAsync<T>(filePath);
        }
        public Task<T> DeserializeFromTextAssetAsync<T>(TextAsset textAsset)
        {
            return DeserializeAsync<T>(textAsset.text);
        }

        public void AddCustomDeserializationFunction<T>(Func<string, T> deserializationFunction)
        {
            winMLDeserializer.AddDeserializationFunction(deserializationFunction);
        }
    }
}